import 'package:flutter/material.dart';
import 'grouped_buttons_orientation.dart';

class GwCheckboxGroup extends StatefulWidget {
  /// 选项
  final List<String> labels;
  // 选中
  final List<String>? selectList;
  // 不可用
  final List<String>? disabled;

  final void Function(bool isChecked, String label, int index)? onChange;

  /// 选中event
  final void Function(List<String> selected)? onSelected;

  final TextStyle labelStyle;
  // 不能选中LabelStyle
  final TextStyle disableLabelStyle;
  // 边框
  final BorderSide? side;
  // 不能选中边框
  final BorderSide? disableSide;

  final GroupedButtonsOrientation orientation;

  final Widget Function(Checkbox checkBox, Text label, int index)? itemBuilder;

  /// The color to use when a Checkbox is checked.
  final Color? activeColor;

  /// The color to use for the check icon when a Checkbox is checked.
  final Color checkColor;

  /// If true the checkbox's value can be true, false, or null.
  final bool tristate;

  final EdgeInsetsGeometry padding;

  final EdgeInsetsGeometry margin;

  const GwCheckboxGroup({
    Key? key,
    required this.labels,
    this.selectList,
    this.disabled,
    this.onChange,
    this.onSelected,
    this.labelStyle = const TextStyle(),
    this.disableLabelStyle = const TextStyle(color: Colors.grey),
    this.side = const BorderSide(color: Colors.black),
    this.disableSide = const BorderSide(color: Colors.grey),
    this.activeColor = Colors.blue, //defaults to toggleableActiveColor,
    this.checkColor = Colors.white,
    this.tristate = false,
    this.orientation = GroupedButtonsOrientation.VERTICAL,
    this.itemBuilder,
    this.padding = const EdgeInsets.all(0.0),
    this.margin = const EdgeInsets.all(0.0),
  }) : super(key: key);

  @override
  _GwCheckboxGroupState createState() => _GwCheckboxGroupState();
}

class _GwCheckboxGroupState extends State<GwCheckboxGroup> {
  List<String> _select = <String>[];
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _select.addAll(widget.selectList ?? []);
  }

  @override
  void reassemble() {
    // TODO: implement reassemble
    super.reassemble();
    _select.addAll(widget.selectList ?? []);
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> content = [];

    for (int i = 0; i < widget.labels.length; i++) {
      bool isDisbled = (widget.disabled != null &&
          widget.disabled!.contains(widget.labels.elementAt(i)));
      Checkbox cb = Checkbox(
        value: _select.contains(widget.labels.elementAt(i)),
        onChanged: (value) {
          if (widget.disabled != null &&
              widget.disabled!.contains(widget.labels.elementAt(i))) {
            return;
          }
          onChanged(value, i);
        },
        side: isDisbled ? widget.disableSide : widget.side,
        checkColor: widget.checkColor,
        activeColor:
            widget.activeColor ?? Theme.of(context).toggleableActiveColor,
        tristate: widget.tristate,
      );

      Text t = Text(widget.labels.elementAt(i),
          style: isDisbled ? widget.disableLabelStyle : widget.labelStyle);

      //use user defined method to build
      if (widget.itemBuilder != null) {
        content.add(widget.itemBuilder!(cb, t, i));
      } else {
        //vertical orientation means Column with Row inside
        if (widget.orientation == GroupedButtonsOrientation.VERTICAL) {
          content.add(Row(children: <Widget>[
            const SizedBox(width: 12.0),
            cb,
            const SizedBox(width: 12.0),
            t,
          ]));
        } else {
          //horizontal orientation means Row with Column inside

          content.add(Column(children: <Widget>[
            cb,
            const SizedBox(width: 12.0),
            t,
          ]));
        }
      }
    }

    return Container(
      padding: widget.padding,
      margin: widget.margin,
      child: widget.orientation == GroupedButtonsOrientation.VERTICAL
          ? Column(children: content)
          : Row(children: content),
    );
  }

  void onChanged(bool? isChecked, int i) {
    if (isChecked == null) {
      return;
    }
    bool isAlreadyContained = _select.contains(widget.labels.elementAt(i));

    if (mounted) {
      setState(() {
        if (!isChecked && isAlreadyContained) {
          _select.remove(widget.labels.elementAt(i));
        } else if (isChecked && !isAlreadyContained) {
          _select.add(widget.labels.elementAt(i));
        }

        if (widget.onChange != null) {
          widget.onChange!(isChecked, widget.labels.elementAt(i), i);
        }
        if (widget.onSelected != null) widget.onSelected!(_select);
      });
    }
  }
}
